﻿//【初阶】23.模版进阶+继承

//【头文件包含】
//C++的主要头文件
#include<iostream>//c++的输入输出流
using std::cout, std::endl, std::cin;

#include<stack>
#include<queue>
#include<string>
#include<deque>;
using std::deque;
using std::stack;
using std::queue;
using std::string;
//C的主要头文件
//#include<stdio.h>
//#include<stdlib.h>
//#include<assert.h>
//#include<string.h> 
#include<vector>;
using std::vector;
using std::priority_queue;


#include"Func.h"




//【命名空间】

//【结构体声明】【类声明】
//非类型模版参数
template<class T,int N>
class Array
{
public:

private:
	T _a[N];
};
//模版的特化
template<class T>
bool IsEquale(T& left, T& right)
{
	return left == right;
}
template<>
bool IsEquale<char*>(char*& left, char*& right)
{
	return strcmp(left, right) == 0;
}

//继承演示
/*基类*/class Person
{
public: 
	void Print_Inform()
	{
		cout << "name:" << _name << endl;
		cout << "age:" << _age << endl;
	}
protected:
	string _name = "peter";
	int _age=18;
};
/*派生类*/class Student :public Person
{
public:
	void Print_Stu_Ifm()
	{
		Print_Inform();
		cout << "stuid:" << _stuid << endl;
		cout << "S_age:" << _age << endl;
		cout << "P_age:" <<Person::_age << endl;
	}
protected:
	int _stuid=10000001;
	int _age = 20;

};
/*派生类*/struct Teacher : Person
{
protected:
	int _jobid;
};
//【函数声明】
void Test1();void Test2();void Test3(); 


//【主函数】
int main()
{
	
	Test1();
	Test2();
	Test3();
    
	cout << "****主函数结束****" << endl;
	return 0;
}

/*测试用例*/void Test1()
{
	cout << "****测试用例开始****"<< endl;
	Array<int, 1000>arr;
	//Array<int, n>b;不能是变量，结果必须编译时被确认

	int a = 0;int  b = 1;
	cout << IsEquale(a,b) << endl;
	const char* p1 = "hello";
	const char* p2 = "hello";
	cout << IsEquale(p1, p2) << endl;
	cout << "****测试用例结束****" << endl << endl;
}
/*测试用例*/void Test2()
{
	cout << "****测试用例开始****" << endl;
	F1();
	F2(10);
	F3(20);
	cout << "****测试用例结束****" << endl<<endl;
}

/*测试用例*/void Test3()
{
	cout << "****测试用例开始****" << endl;
	Student s;
	Teacher t;
	s.Print_Inform();
	t.Print_Inform();
	s.Print_Stu_Ifm();

	Person p;
	p = s;
	Person* ptr = &s;
	Person& ref = s;
	cout << "****测试用例结束****" << endl << endl;
}



//【笔记】
//【初阶】23.模版进阶+继承
	//模版函数使用template<class T>或template<typename T>,这些都叫类型模版参数
	//非类型模版参数
		// 给定一个固定类型的模版参数，可以通过设置非类型模版参数的值来实现创建不同的对象
		// 非类型模版参数视为一个常量不可被作为左值修改
		// 不能做非类型模版参数的类型有浮点型、类对象及字符串
		// 必须在编译器确认非类型模版参数的结果,相当于必须是常量
	//模版的特化
		//可以是模版中某些类型按需要特除处理，这样在调用该对应类型时会使用特化的模版
		//特化分为全特化和偏特化//可以特化部分参数也可以对参数进行进一步限制
	//分离编译// 目的是为提高代码可读性和可维护性
		// 指在项目工程中一般将函数或类的声明放到.h将函数或者类的定义放到.cpp
		// 而模版函数不能分离编译
		// 函数运行时会通过预处理->编译->汇编->链接几个步骤
		//模版函数不能分离编译的原因是因为在实例化时不能正确链接到定义位置
		//显式实例化能部分解决模版分离编译的问题，但最佳办法是模版函数不分离编译
	//继承：核心是复用
		// 继承结构由 派生类 ：继承方式 基类 组成
		// 继承方式
			// public    ：基类的public，在public的继承下派生类可见
			// protected ：基类的protected在public、protected继承下的派生类可见
			// private   ：基类的private在派生类任何继承下都不可见
			//权限大小排序如下public>protected>private
			//派生类不明确继承方式class默认私有、struct默认公有
		//基类和派生类赋值兼容规则
			//派生类对象可以赋值给基类对象/指针/引用  这种赋值方式叫做切片或切割
		//继承中的作用域
			//基类和派生类有各自独立的作用域
			// 如果父类和子类同时有同名成员时，子类成员隐藏了父类的成员(重定义)
			// 如果需要使用基类则需要直接指定为基类，否则无法调用基类重名的成员变量或成员函数
